package com.androidxmpp;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import android.app.Activity;
import android.content.AsyncQueryHandler;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextWatcher;
import android.text.style.ImageSpan;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.androidxmpp.adapter.ChatAdapter;
import com.androidxmpp.adapter.FaceAdapter;
import com.androidxmpp.adapter.FacePageAdeapter;
import com.androidxmpp.config.ChatConstants;
import com.androidxmpp.config.PreferenceConstants;
import com.androidxmpp.db.ChatProvider;
import com.androidxmpp.db.RosterProvider;
import com.androidxmpp.service.IConnectionStatusCallback;
import com.androidxmpp.service.XMPPService;
import com.androidxmpp.ui.CirclePageIndicator;
import com.androidxmpp.ui.MsgListView;
import com.androidxmpp.ui.MsgListView.IXListViewListener;
import com.androidxmpp.util.LogUtil;
import com.androidxmpp.util.PreferenceUtils;
import com.androidxmpp.util.StatusMode;
import com.androidxmpp.util.ToastUtil;
import com.androidxmpp.util.XMPPHelper;

/**
 * 聊天
 * 
 * @author chen_fulei
 * 
 */
public class ChatActivity extends Activity implements OnClickListener,
		OnTouchListener, IConnectionStatusCallback, IXListViewListener {
	public static final String INTENT_EXTRA_USERNAME = ChatActivity.class
			.getName() + ".username";// 昵称对应的key

	private static final String[] PROJECTION_FROM = new String[] {
			ChatProvider.ChatConstants._ID, ChatProvider.ChatConstants.DATE,
			ChatProvider.ChatConstants.DIRECTION,
			ChatProvider.ChatConstants.JID, ChatProvider.ChatConstants.MESSAGE,
			ChatProvider.ChatConstants.DELIVERY_STATUS };// 查询字段

	// 查询联系人数据库字段
	private static final String[] STATUS_QUERY = new String[] {
			RosterProvider.RosterConstants.STATUS_MODE,
			RosterProvider.RosterConstants.STATUS_MESSAGE, };

	private final Activity activity = this;

	private ImageButton btn_back; // 返回
	private TextView ivTitleName;// 用户名
	private ImageView ivTitleStatus;// 用户在线状态
	private ProgressBar ivTitleProgress;

	private MsgListView msg_listView;
	private ImageButton face_switch_btn;// 表情
	private EditText ed_input;// 输入内容
	private Button btn_send;// 发送信息

	// 表情
	private LinearLayout face_ll;
	private ViewPager mFaceViewPager;
	private int mCurrentPage = 0;// 当前表情页
	private boolean mIsFaceShow = false;// 是否显示表情
	private List<String> mFaceMapKeys;// 表情对应的字符串数组
	private String mWithJabberID = null;// 当前聊天用户的ID

	private WindowManager.LayoutParams mWindowNanagerParams;
	private InputMethodManager mInputMethodManager;

	private XMPPService xmppService;// 全局的服务
	private ContentObserver mContactObserver = new ContactObserver();// 联系人数据监听，主要是监听对方在线状态

	// 启动服务
	private ServiceConnection mServiceConnection = new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
			xmppService.unRegisterConnectionStatusCallback();
			xmppService = null;
		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			xmppService = ((XMPPService.XMPPBinder) service).getService();
			xmppService.registerConnectionStatusCallback(ChatActivity.this);
			// 如果没有连接上，则重新连接xmpp服务器
			if (!xmppService.isAuthenticated()) {
				String usr = PreferenceUtils.getPrefString(ChatActivity.this,
						PreferenceConstants.ACCOUNT, "");
				String password = PreferenceUtils.getPrefString(
						ChatActivity.this, PreferenceConstants.PASSWORD, "");
				xmppService.Login(usr, password);
			}
		}
	};

	/**
	 * 解绑服务
	 */
	private void unbindXMPPService() {
		try {
			unbindService(mServiceConnection);
		} catch (IllegalArgumentException e) {
			LogUtil.e("Service wasn't bound!");
		}
	}

	/**
	 * 绑定服务
	 */
	private void bindXMPPService() {
		Intent mServiceIntent = new Intent(this, XMPPService.class);
		Uri chatURI = Uri.parse(mWithJabberID);
		mServiceIntent.setData(chatURI);
		bindService(mServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.act_chat);
		initData();// 初始化数据
		initView();
		initFacePage();// 初始化表情
		setChatWindowAdapter();//获得聊天纪录
		//updateContactStatus();// 获取联系人
		getContentResolver().registerContentObserver(
				RosterProvider.CONTENT_URI, true, mContactObserver);// 开始监听联系人数据库
	}

	/**
	 * 初始化控件
	 */
	private void initView() {
		mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
		mWindowNanagerParams = getWindow().getAttributes();

		btn_back = (ImageButton) findViewById(R.id.btn_back);
		ivTitleName = (TextView) findViewById(R.id.ivTitleName);
		ivTitleStatus = (ImageView) findViewById(R.id.ivTitleStatus);
		ivTitleProgress = (ProgressBar) findViewById(R.id.ivTitleProgress);

		msg_listView = (MsgListView) findViewById(R.id.msg_listView);
		face_switch_btn = (ImageButton) findViewById(R.id.face_switch_btn);
		ed_input = (EditText) findViewById(R.id.ed_input);
		btn_send = (Button) findViewById(R.id.btn_send);
		btn_send.setEnabled(false);

		face_ll = (LinearLayout) findViewById(R.id.face_ll);
		mFaceViewPager = (ViewPager) findViewById(R.id.face_pager);

		btn_back.setOnClickListener(this);
		btn_send.setOnClickListener(this);
		face_switch_btn.setOnClickListener(this);

		msg_listView.setOnTouchListener(this);
		msg_listView.setPullLoadEnable(false);
		msg_listView.setXListViewListener(this);
		ed_input.setOnTouchListener(this);
		ed_input.setOnKeyListener(new OnKeyListener() {

			@Override
			public boolean onKey(View view, int keyCode, KeyEvent event) {

				if (keyCode == KeyEvent.KEYCODE_BACK) {
					if (mWindowNanagerParams.softInputMode == WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
							|| mIsFaceShow) {
						face_ll.setVisibility(View.GONE);
						mIsFaceShow = false;
						return true;
					}
				}
				return false;
			}
		});

		ed_input.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {

			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {

			}

			@Override
			public void afterTextChanged(Editable s) {
				if (s.length() > 0) {
					btn_send.setEnabled(true);
				} else {
					btn_send.setEnabled(false);
				}
			}
		});

	}

	private void initData() {
		mWithJabberID = getIntent().getDataString().toLowerCase();// 获取聊天对象的id
		// 将表情map的key保存在数组中
		Set<String> keySet = MyApp.getInstance().getFaceMap().keySet();
		mFaceMapKeys = new ArrayList<String>();
		mFaceMapKeys.addAll(keySet);
	}

	/**
	 * 初始化表情
	 */
	private void initFacePage() {
		List<View> lv = new ArrayList<View>();
		for (int i = 0; i < MyApp.NUM_PAGE; i++) {
			lv.add(getGridView(i));
		}

		FacePageAdeapter adapter = new FacePageAdeapter(lv);
		mFaceViewPager.setAdapter(adapter);
		mFaceViewPager.setCurrentItem(mCurrentPage);
		CirclePageIndicator indicator = (CirclePageIndicator) findViewById(R.id.indicator);
		indicator.setViewPager(mFaceViewPager);
		adapter.notifyDataSetChanged();
		face_ll.setVisibility(View.GONE);

		indicator.setOnPageChangeListener(new OnPageChangeListener() {

			@Override
			public void onPageSelected(int arg0) {
				// TODO Auto-generated method stub
				mCurrentPage = arg0;
			}

			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onPageScrollStateChanged(int arg0) {
				// TODO Auto-generated method stub

			}
		});
	}

	/**
	 * 
	 * @param i
	 * @return
	 */
	private GridView getGridView(int i) {
		GridView gv = new GridView(this);
		gv.setNumColumns(7);
		gv.setSelector(new ColorDrawable(Color.TRANSPARENT));// 屏蔽GridView默认点击效果
		gv.setBackgroundColor(Color.TRANSPARENT);
		gv.setCacheColorHint(Color.TRANSPARENT);
		gv.setHorizontalSpacing(1);
		gv.setVerticalSpacing(1);
		gv.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
				LayoutParams.MATCH_PARENT));
		gv.setGravity(Gravity.CENTER);
		FaceAdapter adapter = new FaceAdapter(this, i);
		gv.setAdapter(adapter);
		gv.setOnTouchListener(forbidenScroll());
		gv.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View convertView,
					int position, long arg) {
				if (position == MyApp.NUM) {// 删除键的位置
					int selection = ed_input.getSelectionStart();
					String text = ed_input.getText().toString();
					if (selection > 0) {
						String text2 = text.substring(selection - 1);
						if ("]".equals(text2)) {
							int start = text.lastIndexOf("[");
							int end = selection;
							ed_input.getText().delete(start, end);
							return;
						}
						ed_input.getText()
								.delete(selection - 1, selection);
					}
				} else {
					int count = mCurrentPage * MyApp.NUM + position;

					// 下面这部分，在EditText中显示表情
					Bitmap bitmap = BitmapFactory.decodeResource(
							getResources(), (Integer) MyApp.getInstance()
									.getFaceMap().values().toArray()[count]);
					if (bitmap != null) {
						int rawHeigh = bitmap.getHeight();
						int rawWidth = bitmap.getHeight();
						int newHeight = 40;
						int newWidth = 40;
						// 计算缩放因子
						float heightScale = ((float) newHeight) / rawHeigh;
						float widthScale = ((float) newWidth) / rawWidth;
						// 新建立矩阵
						Matrix matrix = new Matrix();
						matrix.postScale(heightScale, widthScale);
						// 设置图片的旋转角度
						// matrix.postRotate(-30);
						// 设置图片的倾斜
						// matrix.postSkew(0.1f, 0.1f);
						// 将图片大小压缩
						// 压缩后图片的宽和高以及kB大小均会变化
						Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0,
								rawWidth, rawHeigh, matrix, true);
						ImageSpan imageSpan = new ImageSpan(ChatActivity.this,
								newBitmap);
						String emojiStr = mFaceMapKeys.get(count);
						SpannableString spannableString = new SpannableString(
								emojiStr);
						spannableString.setSpan(imageSpan,
								emojiStr.indexOf('['),
								emojiStr.indexOf(']') + 1,
								Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
						ed_input.append(spannableString);
					} else {
						String ori = ed_input.getText().toString();
						int index = ed_input.getSelectionStart();
						StringBuilder stringBuilder = new StringBuilder(ori);
						stringBuilder.insert(index, mFaceMapKeys.get(count));
						ed_input.setText(stringBuilder.toString());
						ed_input.setSelection(index
								+ mFaceMapKeys.get(count).length());
					}
				}
			}
		});

		return gv;
	}

	// 防止乱pageview乱滚动
	private OnTouchListener forbidenScroll() {
		return new OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {
				if (event.getAction() == MotionEvent.ACTION_MOVE) {
					return true;
				}
				return false;
			}
		};
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_back:
			// 返回
			overridePendingTransition(R.anim.enteralpha, R.anim.exitalpha);
			activity.finish();

			break;

		case R.id.btn_send:
			// 发送信息
			sendMessageIfNotNull();
			break;

		case R.id.face_switch_btn:
			Toast.makeText(activity, "face", Toast.LENGTH_SHORT).show();
			if (!mIsFaceShow) {
				mInputMethodManager.hideSoftInputFromWindow(
						ed_input.getWindowToken(), 0);
				try {
					Thread.sleep(80);// 解决此时会黑一下屏幕的问题
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				face_ll.setVisibility(View.VISIBLE);
				face_switch_btn.setImageResource(R.drawable.aio_keyboard);
				mIsFaceShow = true;
			} else {
				face_ll.setVisibility(View.GONE);
				mInputMethodManager.showSoftInput(ed_input, 0);
				face_switch_btn
						.setImageResource(R.drawable.qzone_edit_face_drawable);
				mIsFaceShow = false;
			}

			break;

		default:
			break;
		}
	}

	private void sendMessageIfNotNull() {
		if (ed_input.getText().length() >= 1) {
			if (xmppService != null) {
				xmppService.sendMessage(mWithJabberID, ed_input.getText()
						.toString());
				if (!xmppService.isAuthenticated())
					ToastUtil.showShort(this, "消息已经保存随后发送");
			}
			ed_input.setText(null);
			btn_send.setEnabled(false);
		}
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		switch (v.getId()) {
		case R.id.msg_listView:
			mInputMethodManager.hideSoftInputFromWindow(
					ed_input.getWindowToken(), 0);
			face_switch_btn
					.setImageResource(R.drawable.qzone_edit_face_drawable);
			face_ll.setVisibility(View.GONE);
			mIsFaceShow = false;
			break;
		case R.id.ed_input:
			mInputMethodManager.showSoftInput(ed_input, 0);
			face_switch_btn
					.setImageResource(R.drawable.qzone_edit_face_drawable);
			face_ll.setVisibility(View.GONE);
			mIsFaceShow = false;
			break;

		default:
			break;
		}

		return false;
	}

	@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		super.onWindowFocusChanged(hasFocus);
		// 绑定服务
		if (hasFocus) {
			bindXMPPService();
		} else {
			unbindXMPPService();
		}
	}

	@Override
	public void connectionStatusChanged(int connectedState, String reason) {

	}

	// 查询联系人
	private void updateContactStatus() {
		Cursor cursor = getContentResolver().query(RosterProvider.CONTENT_URI,
				STATUS_QUERY, RosterProvider.RosterConstants.JID + " = ?",
				new String[] { mWithJabberID }, null);
		int MODE_IDX = cursor
				.getColumnIndex(RosterProvider.RosterConstants.STATUS_MODE);
		int MSG_IDX = cursor
				.getColumnIndex(RosterProvider.RosterConstants.STATUS_MESSAGE);

		if (cursor.getCount() == 1) {
			cursor.moveToFirst();
			int status_mode = cursor.getInt(MODE_IDX);
			String status_message = cursor.getString(MSG_IDX);
			LogUtil.d("contact status changed: " + status_mode + " "
					+ status_message);
			ivTitleName.setText(XMPPHelper.splitJidAndServer(getIntent()
					.getStringExtra(INTENT_EXTRA_USERNAME)));
			int statusId = StatusMode.values()[status_mode].getDrawableId();
			if (statusId != -1) {// 如果对应离线状态
				// Drawable icon = getResources().getDrawable(statusId);
				// mTitleNameView.setCompoundDrawablesWithIntrinsicBounds(icon,
				// null,
				// null, null);
				ivTitleStatus.setImageResource(statusId);
				ivTitleStatus.setVisibility(View.VISIBLE);
			} else {
				ivTitleStatus.setVisibility(View.GONE);
			}
		}
		cursor.close();
	}

	/**
	 * 联系人数据库变化监听
	 * 
	 */
	private class ContactObserver extends ContentObserver {
		public ContactObserver() {
			super(new Handler());
		}

		public void onChange(boolean selfChange) {
			LogUtil.d("ContactObserver.onChange: " + selfChange);
			updateContactStatus();// 联系人状态变化时，刷新界面
		}
	}

	/**
	 * 设置聊天的Adapter
	 */
	private void setChatWindowAdapter() {
		String selection = ChatConstants.JID + "='" + mWithJabberID + "'";
		// 异步查询数据库
		new AsyncQueryHandler(getContentResolver()) {

			@Override
			protected void onQueryComplete(int token, Object cookie,
					Cursor cursor) {
				// ListAdapter adapter = new ChatWindowAdapter(cursor,
				// PROJECTION_FROM, PROJECTION_TO, mWithJabberID);
				ListAdapter adapter = new ChatAdapter(ChatActivity.this,
						cursor, PROJECTION_FROM);
				msg_listView.setAdapter(adapter);
				msg_listView.setSelection(adapter.getCount() - 1);
			}

		}.startQuery(0, null, ChatProvider.CONTENT_URI, PROJECTION_FROM,
				selection, null, null);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (hasWindowFocus())
			unbindXMPPService();// 解绑服务
		getContentResolver().unregisterContentObserver(mContactObserver);
	}

	@Override
	public void onRefresh() {
		msg_listView.stopRefresh();
	}

	@Override
	public void onLoadMore() {

	}
	
	@Override
	public void onBackPressed() {
		super.onBackPressed();
		overridePendingTransition(R.anim.enteralpha, R.anim.exitalpha);
		finish();
	}

	@Override
	protected void onResume() {
		super.onResume();
		updateContactStatus();
	}
}
